package com.googlecode.vmock.matchers;

import com.googlecode.vmock.matchers.ranking.MatcherRanking;
import com.googlecode.vmock.utils.Validate;

/**
 * A matcher that matches all values which are not matched by a given matcher.
 * 
 * @author marcin.jagus
 */
public class NegationMatcher implements Matcher {

    private Matcher matcher;

    /**
     * Creates a matcher that matches all values not matched by a given matcher.
     * 
     * @param matcher Given matcher
     */
    public NegationMatcher(Matcher matcher) {
        Validate.notNull(matcher, "matcher == null");

        this.matcher = matcher;
    }

    @Override
    public int compareTo(Matcher m) {
        Integer thisRanking = MatcherRanking.getRanking(matcher.getClass());
        Integer theirRanking = MatcherRanking.getRanking(m.getClass());

        if (thisRanking != null && theirRanking != null) {
            thisRanking = MatcherRanking.getMaxRanking() - thisRanking;

            return thisRanking.compareTo(theirRanking);
        } else {
            return -1 * matcher.compareTo(m);
        }
    }

    @Override
    public boolean matches(Object value) {
        return !matcher.matches(value);
    }

    @Override
    public String toString() {
        return String.format("NegationMatcher(%s)", matcher);
    }
}
